//////////////////////////////////////////////
// RenderQueue.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward decl -----------------------------

namespace nkGraphics
{
	class Buffer ;
	class Entity ;
	class EntityRenderInfo ;
	class EntityRenderInfoSlot ;
	class EntityRenderLodSlot ;
	class Mesh ;
	class Node ;
	class RenderCommandQueue ;
	class RenderStrategy ;
	class Shader ;
	class System ;
}

/// Includes ---------------------------------

// nkGraphics
#include "../Dll/DllDefines.h"

// nkExport
#include <NilkinsExport/Exportable/Exportable.h>

// nkMemory
#include <NilkinsMemory/Containers/BufferCast.h>
#include <NilkinsMemory/Containers/String.h>
#include <NilkinsMemory/Containers/StringView.h>

#include <NilkinsMemory/Pointers/UniquePtr.h>

/// Class ------------------------------------

namespace nkGraphics
{
	class DLL_GRAPHICS_EXPORT RenderQueue : public nkExport::Exportable
	{		
		public :

			// Destructor
			virtual ~RenderQueue () ;
		
			// Getters
			virtual Buffer* getAccelerationStructureBuffer () const ;
			System* getSystem () const ;
			nkMemory::StringView getName () const ;
			bool getRaytraced () const ;
			bool getHidden () const ;
			Entity* getEntity (unsigned int index) const ;
			unsigned int getEntityCount () const ;
			RenderStrategy* getRenderStrategy () const ;

			// Setters
			virtual void setName (nkMemory::StringView name) ;
			virtual void setRaytraced (bool value) ;
			void setRenderStrategy (RenderStrategy* value) ;
			void setHidden (bool value) ;

			// Entity management
			virtual Entity* addEntity () ;
			virtual void eraseEntity (Entity* ent) ;
			virtual void clearQueue () ;

			// Queue baking
			RenderCommandQueue bakeRenderCommandQueue (Shader* shader = nullptr, bool transparent = false) ;

			// Update entities
			virtual void updateEntityNode (Entity* ent, Node* oldNode) ;
			virtual void updateEntityRenderInfo (Entity* ent, EntityRenderInfo* oldInfo, EntityRenderInfo* newInfo) ;
			virtual void updateMesh (Entity* ent, EntityRenderInfoSlot* slot, EntityRenderLodSlot* lod, Mesh* oldMesh, Mesh* newMesh) ;
			virtual void updateShader (Entity* ent, EntityRenderInfoSlot* slot, EntityRenderLodSlot* lod, Shader* oldShader, Shader* newShader) ;
			virtual void updateShaderRaytracing (Entity* ent, EntityRenderInfoSlot* slot, EntityRenderLodSlot* lod, Shader* oldShader, Shader* newShader) ;

			// Import / Export
			virtual void exportClassToTree (nkExport::Node* rootNode) override ;
			virtual void importClassFromTree (nkExport::Node* rootNode) override ;

		public :

			// Statics
			static nkMemory::UniquePtr<RenderQueue> create (System* system = nullptr) ;

		protected :

			// Fonctions
			// Constructor
			RenderQueue (System* system) noexcept ;

		protected :
		
			// Attributes
			// Arrays managed
			nkMemory::BufferCast<Entity*> _entities ;

			// Parent system
			System* _system ;

			// Queue name
			nkMemory::String _name ;

			// Strategy used
			RenderStrategy* _renderStrategy ;

			// Hidden for global resource exports
			bool _hidden ;
			// Whether raytracing for this RQ should be enabled
			bool _raytraced ;

			// Internal flags
			bool _ownsStrategy ;
	} ;
}